home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / gs24src.zip / GSMAIN.C < prev    next >
C/C++ Source or Header  |  1992-03-06  |  6KB  |  216 lines

  1. /* Copyright (C) 1989, 1992 Aladdin Enterprises.  All rights reserved.
  2.    Distributed by Free Software Foundation, Inc.
  3.  
  4. This file is part of Ghostscript.
  5.  
  6. Ghostscript is distributed in the hope that it will be useful, but
  7. WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
  8. to anyone for the consequences of using it or for whether it serves any
  9. particular purpose or works at all, unless he says so in writing.  Refer
  10. to the Ghostscript General Public License for full details.
  11.  
  12. Everyone is granted permission to copy, modify and redistribute
  13. Ghostscript, but only under the conditions described in the Ghostscript
  14. General Public License.  A copy of this license is supposed to have been
  15. given to you along with Ghostscript so you can know your rights and
  16. responsibilities.  It should be in a file named COPYING.  Among other
  17. things, the copyright notice and this notice must be preserved on all
  18. copies.  */
  19.  
  20. /* gsmain.c */
  21. /* Framework for Ghostscript drivers */
  22. #include "string_.h"
  23. #include "memory_.h"
  24. #include "gx.h"
  25. #include "gp.h"
  26. #include "gsmatrix.h"            /* for gxdevice.h */
  27. #include "gxdevice.h"
  28. #include "gxdevmem.h"
  29.  
  30. /*
  31.  * This routine provides the following standard services for parsing
  32.  * a command line:
  33.  *    - setting debug flags (-A, -e, -E switches);
  34.  *    - tracing (-T, -Z switches) [if debugging];
  35.  *    - passing other arguments and switches back to the caller.
  36.  *
  37.  * Calling convention:
  38.  *    gs_main(argc, argv, map_name, switch_proc, arg_proc)
  39.  * Calls
  40.  *    switch_proc(&switch, rest_of_arg) for switches,
  41.  *    arg_proc(&arg, index) for non-switch args.
  42.  * If switch_proc returns a negative value, gs_main prints an
  43.  *   "unknown switch" error message and aborts.
  44.  * gs_main returns the number of non-switch args handed to arg_proc.
  45.  */
  46.  
  47. /* Imported data */
  48. extern int gs_alloc_debug;
  49. extern int gs_log_errors;
  50. extern gx_device *gx_device_list[];
  51.  
  52. void gs_exit(P1(int));
  53.  
  54. int
  55. gs_main(int argc, char *argv[], const char *map_name,
  56.     int (*switch_proc)(P2(char **, char *)),
  57.     void (*arg_proc)(P2(char **, int)))
  58. {    int argi = 1;
  59.     FILE *mapf = NULL;
  60.     int arg_count = 0;
  61.     gs_log_errors = 0;
  62.     gs_out = stdout;
  63. #ifdef DEBUG
  64.     gs_debug_out = stdout;
  65.     /* Reset debugging flags */
  66.     memset(gs_debug, 0, 128);
  67. #endif
  68.     /* If debugging is enabled, trace the device calls. */
  69. #ifdef DEBUG
  70.        {    extern gx_device *gs_trace_device(P1(gx_device *));
  71.         extern gx_device_memory
  72.             mem_mono_device, mem_mapped8_color_device,
  73.             mem_true24_color_device, mem_true32_color_device;
  74.         static gx_device_memory *mdevs[5] =
  75.            {    &mem_mono_device, &mem_mapped8_color_device,
  76.             &mem_true24_color_device, &mem_true32_color_device,
  77.             0
  78.            };
  79.         extern gx_device gs_clist_device;    /* gx_clist_device */
  80.         static gx_device *cldevs[2] =
  81.            {    &gs_clist_device,
  82.             0
  83.            };
  84.         gx_device **pdevs[4];
  85.         gx_device ***ppdev;
  86.         gx_device **pdev;
  87.         pdevs[0] = gx_device_list;
  88.         pdevs[1] = (gx_device **)mdevs;
  89.         pdevs[2] = cldevs;
  90.         pdevs[3] = 0;
  91. /******
  92.         for ( ppdev = pdevs; *ppdev != 0; ppdev++ )
  93.          for ( pdev = *ppdev; *pdev != 0; pdev++ )
  94.            {    gx_device *tdev = gs_trace_device(*pdev);
  95.             if ( tdev == 0 )
  96.                {    lprintf("Can't allocate traced device!\n");
  97.                 gs_exit(1);
  98.                }
  99.             *pdev = tdev;
  100.            }
  101.  ******/
  102.        }
  103. #endif
  104.     for ( ; argi < argc; argi++ )
  105.        {    char **argp = &argv[argi];
  106.         char *arg = *argp;
  107.         if ( *arg == '-' )
  108.            {    switch ( *++arg )
  109.                {
  110.             default:
  111.                 if ( (*switch_proc)(argp, arg + 1) < 0 )
  112.                     printf("Unknown switch %s - ignoring\n", arg - 1);
  113.                 break;
  114.             case 'A':
  115.                 gs_alloc_debug = 1; break;
  116.             case 'e':
  117.                 gs_log_errors = 1; break;
  118.             case 'E':
  119.                 gs_log_errors = 2; break;
  120.             case 'Z':
  121. #ifdef DEBUG
  122.                 /* Print the address of 'main' so that */
  123.                 /* we can decipher stack traces later. */
  124.                {    extern main();
  125.                 printf("[Z]main = %lx\n", (ulong)main);
  126.                }
  127.                 if ( !arg[1] )
  128.                    {    /* No options, set all flags */
  129.                     memset(gs_debug, 0xff, 128);
  130.                    }
  131.                 else
  132.                    {    while ( *++arg )
  133.                         gs_debug[*arg & 127] = 0xff;
  134.                    }
  135. #else
  136.                 printf("Not a debugging configuration, -Z switch ignored\n");
  137. #endif
  138.                 break;
  139.             case 'T':
  140.             if ( mapf == NULL )
  141.                {    /* Open the map file and look up 'main' */
  142.                 extern FILE *trace_open_map(P2(const char *, long *));
  143.                 mapf = trace_open_map(map_name, NULL);
  144.                 if ( mapf == NULL )
  145.                    {    printf("Map file %s is apparently missing or malformed\n", map_name);
  146.                     break;
  147.                    }
  148.                 /* Print the address of 'main' so that */
  149.                 /* we can decipher return addresses later. */
  150.                {    extern main();
  151.                 printf("[T]main = %lx\n", (ulong)main);
  152.                }
  153.                }
  154.                {    char *delim;
  155.                 char *tname;
  156.                 char *targs = NULL;
  157.                 int rsize = 0;
  158.                 extern int trace_flush_flag;
  159.                 delim = strchr(arg, ':');
  160.                 if ( delim != NULL )
  161.                    {    sscanf(delim + 1, "%d", &rsize);
  162.                     *delim = 0;    /* terminate name */
  163.                     delim = strchr(delim + 1, ':');
  164.                     if ( delim != NULL )
  165.                         targs = delim + 1;
  166.                    }
  167.                 tname = gs_malloc(strlen(arg) + 1, 1,
  168.                           "-T switch");
  169.                 strcpy(tname, arg);
  170.                 *tname = '_';
  171.                 strupr(tname);
  172.                 if ( trace_name(tname, mapf, targs, rsize) < 0 )
  173.                     printf("%s not found\n", tname);
  174.                 trace_flush_flag = 1;
  175.                }
  176.                 break;
  177.                }
  178.            }
  179.         else
  180.             (*arg_proc)(argp, arg_count++);
  181.        }
  182.     return arg_count;
  183. }
  184.  
  185. /* Free all resources and exit. */
  186. void gs_malloc_release(P0());
  187. void file_close_all(P0());
  188. int gs_closedevice(P1(gx_device *));
  189. void
  190. gs_exit(int code)
  191. {    gx_device **pdev = gx_device_list;
  192.     if ( code != 0 ) fflush(stderr);    /* in case of error exit */
  193.     for ( ; *pdev != 0; pdev++ )
  194.       gs_closedevice(*pdev);
  195.     /* Close all open files. */
  196.     file_close_all();
  197.     /* Release all memory acquired with malloc. */
  198.     gs_malloc_release();
  199.     exit(code);
  200. }
  201.  
  202. /* ------ Debugging routines ------ */
  203.  
  204. /* Log an error return */
  205. int
  206. gs_log_error(int err, const char _ds *file, int line)
  207. {    if ( gs_log_errors )
  208.       { if ( file == NULL )
  209.           dprintf1("Returning error %d\n", err);
  210.         else
  211.           dprintf3("%s(%d): returning error %d\n",
  212.                (char *)file, line, err);
  213.       }
  214.     return err;
  215. }
  216.